﻿using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace MyCommon.Serialization
{
    /// <summary>
    /// 封装Framework自带的BinaryFormatter，实现实体直接到Base64字符串的序列化 --郭旭东
    /// </summary>
    public class Base64StringSerializer
    {
        /// <summary>
        /// 将对象序列化Base64字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public string Serialize(object obj)
        {
            var formatter = new BinaryFormatter();
            using (var stream = new MemoryStream())
            {
                formatter.Serialize(stream, obj);
                stream.Position = 0;
                var reader = new StreamReader(stream);
                var buffer = Encoding.Default.GetBytes(reader.ReadToEnd());
                return Convert.ToBase64String(buffer);
            }
        }
        /// <summary>
        /// 将Base64字符串反序列化为对象
        /// </summary>
        /// <typeparam name="T">反序列化结果对象的类型</typeparam>
        /// <param name="input">反序列化前的字符串</param>
        /// <returns></returns>
        public T Deserialize<T>(string input) where T : class
        {
            var buffer = Convert.FromBase64String(input);
            var formatter = new BinaryFormatter();
            using (var stream = new MemoryStream())
            {
                var writer = new StreamWriter(stream);
                writer.Write(Encoding.Default.GetChars(buffer));
                writer.Flush();
                stream.Position = 0;
                return formatter.Deserialize(stream) as T;
            }
        }
        /// <summary>
        /// 通过序列化深拷贝对象
        /// </summary>
        /// <typeparam name="T">拷贝的对象类型</typeparam>
        /// <param name="obj">拷贝的对象</param>
        /// <returns>新对象</returns>
        public T CloneObj<T>(T obj) where T : class
        {
            var formatter = new BinaryFormatter();
            using (var stream = new MemoryStream())
            {
                formatter.Serialize(stream, obj);
                stream.Position = 0;
                return formatter.Deserialize(stream) as T;
            }
        }
    }
}
